<?php

namespace App\V3\V3_2_6\Services;

use App\V3\V3_2_6\Models\LogOutPackageModel;
use App\V3\V3_2_6\Models\LogOutStorageModel;
use App\V3\V3_2_6\Models\LogPackageContentModel;
use App\V3\V3_2_6\Models\LogPackageModel;
use App\V3\V3_2_6\Models\MaterielsTypeModel;
use App\V3\V3_2_6\Models\PackageContentModel;
use App\V3\V3_2_6\Models\PackageModel;
use App\V3\V3_2_6\Models\ProductOrderModel;
use App\V3\V3_2_6\Models\ProductSlaveContentStorageModel;
use App\V3\V3_2_6\Models\SalesReturnInPackageModel;
use App\V3\V3_2_6\Models\SalesReturnPackageModel;
use App\V3\V3_2_6\Models\SellGoodsDetailBatchModel;
use App\V3\V3_2_6\Models\SellGoodsDetailModel;
use App\V3\V3_2_6\Models\SellGoodsListModel;
use App\V3\V3_2_6\Models\SellMaterielPrepareOutLogModel;
use App\V3\V3_2_6\Models\SellModel;
use App\V3\V3_2_6\Models\SellOutStoragePackageContentModel;
use App\V3\V3_2_6\Models\SellOutStoragePackageModel;
use App\V3\V3_2_6\Models\SellPackageBatchModel;
use App\V3\V3_2_6\Models\SellPackageContentModel;
use App\V3\V3_2_6\Models\SellPackageContentPrepareOutLogModel;
use App\V3\V3_2_6\Models\SellPackageDetailModel;
use App\V3\V3_2_6\Models\SellPackagePrepareOutLogModel;
use App\V3\V3_2_6\Models\SerialNumberModel;
use App\V3\V3_2_6\Models\StorageBatchModel;
use App\V3\V3_2_6\Models\StorageManageModel;
use App\V3\V3_2_6\Models\StorageModel;
use App\V3\Api\Services\StorageManageService;
use App\V3\V3_2_6\Models\CheckModel;
use App\V3\V3_2_6\Models\SalesReturnGoodsDetailModel;
use App\V3\V3_2_6\Models\SalesReturnModel;
use App\V3\V3_2_6\Models\SellGoodsDetail;
use App\V3\V3_2_6\Models\SellOutStorageModel;
use App\Services\MessageService;
use Facade\Ignition\Support\Packagist\Package;
use Illuminate\Support\Facades\DB;
use Illuminate\Support\Facades\Log;
use App\V3\V3_2_6\Models\SellOutSerialNumbersModel;
use App\V3\V3_2_6\Models\SellPackageSerialNumberModel;
use App\V3\V3_2_6\Models\SalesOutSerialNumberModel;
use App\V3\Api\Models\SalesReturnPackageSerialNumberModel;
use App\V3\V3_2_6\Models\TallyModel;
//use OpenApi\Tests\Annotations\ValidateRelationsTest;

class OutInRepealService
{
    /**
     * 出入库
     * created at 在 2021/11/10 16:13 by Chen Zefeng
     * update at 2022/03/26 17:03 by Sun Wu
     * update content: 增加套餐部分的出入库
     * @param $type 1-销售 2-退款
     * @param $id   主键id
     * @param $status 入库状态：1-部分 2-全部
     * @param $goods  商品信息 obj
     */
    static public function outIn($type,$id,$status,$goods='',$package='',$data)
    {
        $paramsArr = [];//出入库参数
        $paramsArr['all_id'] = $id;
        isset($data['remark'])?$paramsArr['remark'] = $data['remark']:$paramsArr['remark'] = '';
        $paramsArr['all_id_type'] = 2;//销售退货均为2

        switch($type) {
            case 1://销售
                $result = self::sell($paramsArr, $status, $goods, $package, $data, $id);
                break;
//            case 2://退货退款
//                $result = self::refund($paramsArr);
//                break;
        }

        return $result;
    }

    //销售单
    static private function  sell($paramsArr, $status, $goods, $package, $data, $id)
    {
        DB::beginTransaction();

        try {
            $paramsArr['out_storage_time'] = $data['in_storage_time'];

            $result = self::partSell($paramsArr, $id, $goods, $package, $data);
//            //status:0-部分 1-全部
//            switch($status) {
//                case 0:
//                    $result = self::partSell($paramsArr, $id, $goods, $package, $data);
//                    break;
//                case 1:
//                    $result = self::allSell($paramsArr, $id, $goods, $package, $data);
//                    break;
//            }

            return $result;
        }
        catch(\Exception $e) {
            DB::rollBack();
            Log::debug('销售单出库:'.var_export($e->getMessage(),true));
            return ['code' => 1, 'msg' => $e->getMessage(), 'data' => ''];
        }
    }

    //部分出库
    static private function partSell($paramsArr, $id, $goods, $package, $data)
    {
        DB::beginTransaction();
        try {
            //更新销售入库状态
            SellModel::where('id',$id)->update(['out_status'=>1, 'prepare_out_status' => 0]);
            //部分出库临时存储
            $paramsArr['all_id'] = $id;
            isset($data['remark'])?$paramsArr['remark'] = $data['remark']:$paramsArr['remark'] = '';
            $paramsArr['all_id_type'] = 2;//销售退货均为2
            $paramsArr['out_storage_time'] = $data['in_storage_time'];

            if(!empty($goods)) {
                $goodsInfo = json_decode($goods,true);

                foreach($goodsInfo as $key => $value) {
                    /* $minfo = MaterielsTypeModel::select('is_use_serial')->where('id',$value['materiel_type_id'])->first();
                    if($minfo['is_use_serial'] == 1){
                        $serial_no_array = explode(',',$value['serial_no']);

                        if(empty($serial_no_array)){
                            throw new \Exception('序列号不能为空');
                        }

                        if(count($serial_no_array) != $value['num']){
                            throw new \Exception('序列号个数与入库数量不符');
                        }
                        foreach ($serial_no_array as $serial_key => $serial_data){
                            //检查序列号是否使用
                            $number_info = SerialNumberModel::where(['goods_id' => $value['materiel_type_id'],'serial_no' => $serial_data,'status' => SerialNumberModel::UNUSEDSTATUS])->first();

                            if(!$number_info){
                                throw new \Exception('该商品：'.$value['materiel_type_id'].'的序列号：'.$serial_data.'已被使用');
                            }

                            SellOutSerialNumbersModel::insert([

                                'main_id' =>  $data['main_id'],
                                'created_at' => time(),
                                'sell_id' => $data['id'],
                                'type_id' => $number_info['goods_id'],
                                'serial_number' => $serial_data,
                                'status' => 1


                            ]);
                            SerialNumberModel::where(['serial_no' => $serial_data,'status' => SerialNumberModel::UNUSEDSTATUS,
                                'goods_id' => $number_info['goods_id'],
                            ])->update(['status' => SerialNumberModel::USEDSTATUS]);
                        }
                    } */
                    $paramsArr = self::sellMaterielPart($paramsArr, $id, $key, $data, $value);

                    if(isset($paramsArr['code'])) {
                        return $paramsArr;
                    }
                }

                //调用出库
                if(isset($paramsArr['content'])) {
                    $res = StorageManageService::outStorage($data['user_id'], $data['main_id'], $paramsArr, $id);
                    if($res['code']){
                        return $res;
                    }
                }
            }

            if(!empty($package)) {
                $packageInfo = json_decode($package,true);

                $packageOutInfo = self::sellPackagePart($id, $packageInfo, $data);

                if(isset($packageOutInfo['code'])) {
                    return $packageOutInfo;
                }
            }

            $flag = 0;
            $sellGoodsSetailInfo = SellGoodsDetailModel::where('sell_id', $id)->get()->toArray();

            foreach($sellGoodsSetailInfo as $v1) {
                if($v1['num'] == $v1['out_num']) {
                    $flag = 1;
                }
                else {
                    $flag = 0;
                }
            }

            $sellPackageDetailInfo = SellPackageDetailModel::where('sell_id', $id)->get()->toArray();

            foreach($sellPackageDetailInfo as $v2) {
                if($v2['num'] == $v2['out_num']) {
                    $flag = 1;
                }
                else {
                    $flag = 0;
                }
            }

            if($flag) {
                SellModel::where('id',$id)->update(['out_status'=>2,'prepare_out_status' => 0]);//全部完成更新状态
                CheckModel::where(['main_id'=>$data['main_id'],'type'=>2,'all_id'=>$id])
                    ->update(['status'=>1,'out_in_status'=>0]);
            }
            else {
                CheckModel::where(['main_id'=>$data['main_id'],'type'=>2,'all_id'=>$id])
                    ->update(['out_in_status'=>1]);
            }

            DB::commit();
            return ['code' => 0, 'msg' => 'success', 'data' => ''];
        }
        catch(\Exception $e) {
            DB::rollBack();
            Log::debug('销售单出库:'.var_export($e->getMessage(),true));
            return ['code' => 1, 'msg' => $e->getMessage(), 'data' => ''];
        }
    }

    //销售单序列号出库
    static public function outInBySerial($type,$id,$status,$goods='',$package='',$data, $isUseShelf)
    {
        $paramsArr = [];//出入库参数
        $paramsArr['all_id'] = $id;
        isset($data['remark']) ? $paramsArr['remark'] = $data['remark'] : $paramsArr['remark'] = '';
        $paramsArr['all_id_type'] = 2;//销售退货均为2
        $paramsArr['out_storage_time'] = $data['in_storage_time'];

        $serial_array = [];

        DB::beginTransaction();
        try {
            //更新销售入库状态
            SellModel::where('id',$id)->update(['out_status'=>1, 'prepare_out_status' => 0]);
            //部分出库临时存储
            $paramsArr['all_id'] = $id;
            isset($data['remark'])?$paramsArr['remark'] = $data['remark']:$paramsArr['remark'] = '';
            $paramsArr['all_id_type'] = 2;//销售退货均为2
            $paramsArr['out_storage_time'] = $data['in_storage_time'];

            $productContentStorageData = [];
            if(!empty($goods)) {

                $goodsInfo = json_decode($goods,true);
                foreach($goodsInfo as $key => $value) {
                   $value['shelf_id'] = empty($value['shelf_id'])?0:$value['shelf_id'];
                   $value['location_id'] = empty($value['location_id'])?0:$value['location_id'];
                    //查询商品信息
                    $minfo = MaterielsTypeModel::select('is_use_serial')->where('id', $value['materiel_type_id'])->first();
                    if($minfo['is_use_serial'] == 1 && $minfo['is_product_materiel'] == 0){
                        $serial_no_array = explode(',',$value['serial_no']);

                        if(empty($serial_no_array)){
                            throw new \Exception('序列号不能为空');
                        }

                        if(count($serial_no_array) != $value['num']){
                            throw new \Exception('序列号个数与入库数量不符');
                        }
                        foreach ($serial_no_array as $serial_key => $serial_data) {
                            //检查序列号是否使用
                            $number_info = SerialNumberModel::where(['goods_id' => $value['materiel_type_id'],'serial_no' => $serial_data,'status' => SerialNumberModel::UNUSEDSTATUS])->first();

                            if(empty($number_info)){
                                throw new \Exception('该商品：'.$value['materiel_type_id'].'的序列号：'.$serial_data.'不存在');
                            }

                            SellOutSerialNumbersModel::insert([

                                    'main_id' =>  $data['main_id'],
                                    'created_at' => time(),
                                    'sell_id' => $data['id'],
                                    'type_id' => $number_info['goods_id'],
                                    'serial_number' => $serial_data,
                                    'status' => 1
                            ]);

                            $productContentStorageData[] = [
                                'serial_id' => $number_info['id'],
                                'type_id' => $number_info['goods_id'],
                            ];

                            SerialNumberModel::where(['serial_no' => $serial_data,'status' => SerialNumberModel::UNUSEDSTATUS,
                                'goods_id' => $number_info['goods_id'],
                            ])->update(['status' => SerialNumberModel::USEDSTATUS]);
                        }
                    }

                        //查询库存信息
                        //$storageManageInfo = StorageManageModel:: where(['id' => $number_info['storage_manage_id'],'delete_flag' =>0])->first();
                        $storageInfo = StorageModel::where('id', $value['warehouse_id'])->first();

                        //查询商品信息
                        $materielTypeInfo = MaterielsTypeModel::where('id', $value['materiel_type_id'])->first();

                        //销售单商品出库记录
                        $sellOutStorageInfo = SellOutStorageModel::where([
                            'materiel_type_id' => $value['materiel_type_id'],
                            'sell_id' => $id,
                            'shelf_id' => $value['shelf_id'],
                            'location_id' => $value['location_id'],
                        ])->first();

                        //销售单商品信息
                        $sellGoodsDetailInfo = SellGoodsDetailModel::where([
                            'materiel_type_id' => $value['materiel_type_id'],
                            'sell_id' => $id,
//                            'shelf_id' => $value['shelf_id'],
//                            'location_id' => $value['location_id'],
                        ])->first();

                        //验证是否已经出库
                        if(empty($sellOutStorageInfo)) {
                            $datavalue = [];
                            if($sellGoodsDetailInfo['num'] < $value['num']) {
                                return [
                                    'code' => 1,
                                    'msg' => '超出商品最大可出库数量，商品:'.$materielTypeInfo['materiel_name'].'-'.$materielTypeInfo['type_name'].'最大可出库数量为:'.$sellGoodsDetailInfo['num'],
                                    'data' => ''
                                ];
                            }

                            $datavalue['sell_id'] = $id;
                            $datavalue['name'] = $materielTypeInfo['materiel_name'];
                            $datavalue['type_name'] = $materielTypeInfo['type_name'];
                            $datavalue['num'] = $value['num'];
                            $datavalue['price'] = $value['price'];
                            $datavalue['warehouse'] = $storageInfo['storage_name'];
                            $datavalue['warehouse_id'] = $storageInfo['id'];
                            $datavalue['materiel_type_id'] = $materielTypeInfo['id'];
                            $datavalue['remark'] = empty($value['remark'])?'':$value['remark'];

                            $datavalue['shelf_id'] = $value['shelf_id'];
                            $datavalue['location_id'] = $value['location_id'];

                            SellOutStorageModel::insert($datavalue);
                        } else {

                            if($value['num'] > $sellGoodsDetailInfo['num'] - $sellGoodsDetailInfo['out_num']) {
                                return [
                                    'code' => 1,
                                    'msg' => '超出商品最大可出库数量，商品:'.$materielTypeInfo['materiel_name'].'-'.$materielTypeInfo['type_name'].'最大可出库数量为:'.($sellGoodsDetailInfo['num'] - $sellGoodsDetailInfo['out_num']),
                                    'data' => ''
                                ];
                            }
                            SellOutStorageModel::where('id', $sellOutStorageInfo['id'])
                                ->increment('num', $value['num'], [
                                    'remark' => $value['remark']
                                ]);
                        }

                        //更新销售单商品信息已出库数量
                        SellGoodsDetailModel::where('id', $sellGoodsDetailInfo['id'])
                            ->increment('out_num', $value['num']);
                        $paramsArr['content'][$key]['num'] = $value['num'];

                        $paramsArr['content'][$key]['name'] = $materielTypeInfo['materiel_name'];
                        $paramsArr['content'][$key]['price'] = $value['price'];
                        $paramsArr['content'][$key]['type_name'] = $materielTypeInfo['type_name'];
                        $paramsArr['content'][$key]['warehouse'] = $storageInfo['storage_name'];
                        $paramsArr['content'][$key]['warehouse_id'] = $storageInfo['id'];
                        $paramsArr['content'][$key]['serial_no'] = empty($value['serial_no'])?"":$value['serial_no'];
                        $paramsArr['content'][$key]['shelf_id'] = $value['shelf_id'];
                        $paramsArr['content'][$key]['location_id'] = $value['location_id'];
                }
            }
            //调用出库
            if(isset($paramsArr['content'])) {
                $res = StorageManageService::outStorage($data['user_id'], $data['main_id'], $paramsArr, $id, $isUseShelf);
                if($res['code']){
                    return $res;
                }
            }

            if(!empty($package)) {
                $sellInfo = SellModel::where('id', $id)->first();

                $packageInfo = json_decode($package,true);
                $sellGoodsList = [];
                foreach($packageInfo as $value) {
                    $SellPackageDetailInfo = SellPackageDetailModel::select(
                        'a.*',
                        'b.package_name'
                    )
                        ->from('sell_package_detail as a')
                        ->leftJoin('package as b', 'b.id', '=', 'a.package_id')
                        ->where([
                            'sell_id' => $data['id'],
                            'a.package_id' => $value['package_id'],
                            'a.main_id' => $data['main_id'],
                        ])->first()->toArray();

                    if (empty($SellPackageDetailInfo)) {
                        return [
                            'code' => 1,
                            'msg' => '销售单内指定的套餐不存在，无法出库',
                            'data' => ''
                        ];
                    }

                    if ($value['num'] > ($SellPackageDetailInfo['num'] - $SellPackageDetailInfo['out_num'])) {
                        return [
                            'code' => 1,
                            'msg' => '套餐可出库数量不足',
                            'data' => ''
                        ];
                    }
                    $logpackageNewId = LogPackageModel::insertGetId([
                        'package_id' => $value['package_id'],
                        'package_name' => $SellPackageDetailInfo['package_name'],
                        'num' => $SellPackageDetailInfo['num'],
                        'sell_price' => $value['price'],
                        'cost' => sprintf('%.6f', self::getPackageCost($id, $value['package_id']) * $SellPackageDetailInfo['num']),
                        'out_storage_time' => strtotime($data['in_storage_time']),
                        'all_id_type' => 2,
                        'all_id' => $id,
                        'user_id' => $data['user_id'],
                        'main_id' => $data['main_id'],
                        'remark' => empty($value['remark'])?'':$value['remark'],
                        'created_at' => time(),
                    ]);

                    $sellOutStoragePackage = SellOutStoragePackageModel::where([
                        'package_id' => $value['package_id'],
                        'sell_id' => $id
                    ])->first();

                    if (empty($sellOutStoragePackage)) {
                        $sellOutStoragePackageId = SellOutStoragePackageModel::insertGetId([
                            'package_id' => $value['package_id'],
                            'price' => $SellPackageDetailInfo['price'],
                            'num' => $value['num'],
                            'remark' => empty($value['remark'])?'':$value['remark'],
                            'sell_id' => $id
                        ]);

                    } else {
                        $sellOutStoragePackageId = $sellOutStoragePackage['id'];

                        SellOutStoragePackageModel::where('id', $sellOutStoragePackage['id'])
                            ->increment('num', $value['num']);
                    }

                    $package_content_arr = $value['package_content'];

                    foreach ($package_content_arr as $content){

                        $storageManageInfo = StorageManageModel::select('a.*','materiel_type_id')
                        ->from('storage_manage as a')
                        ->leftJoin('sell_package_content as b','b.storage_manage_id','=','a.id')
                        ->where('b.id',$content['package_content_id'])->first();

                            $minfo = MaterielsTypeModel::select('is_use_serial')->where('id',$storageManageInfo['materiel_type_id'])->first();

                            if($minfo['is_use_serial'] == 1){
                                    $serial_no_array = explode(',',$content['serial_no']);

                                    if(empty($serial_no_array)){
                                        throw new \Exception('序列号不能为空');
                                    }

                                    if(count($serial_no_array) != $value['num']*$content['num']){
                                        throw new \Exception('序列号个数与入库数量不符');
                                    }
                                    foreach ($serial_no_array as $serial_key => $serial_data){
                                        //检查序列号是否使用
                                        $number_info = SerialNumberModel::where(['goods_id' => $storageManageInfo['materiel_type_id'],'serial_no' => $serial_data,'status' => SerialNumberModel::UNUSEDSTATUS])->first();

                                        if(!$number_info){
                                            throw new \Exception('该商品：'.$value['materiel_type_id'].'的序列号：'.$serial_data.'已被使用');
                                        }

                                      $id = SellPackageSerialNumberModel::insert([

                                            'main_id' =>  $data['main_id'],
                                            'created_at' => time(),
                                            'sell_id' => $data['id'],
                                            'type_id' => $number_info['goods_id'],
                                            'sell_package_content_id' => $content['package_content_id'],
                                            'serial_number' => $serial_data,
                                            'status' => 1
                                        ]);

                                      SerialNumberModel::where(['serial_no' => $serial_data,'status' => SerialNumberModel::UNUSEDSTATUS,
                                          'goods_id' => $number_info['goods_id'],
                                      ])->update(['status' => SerialNumberModel::USEDSTATUS]);
                                      }
                                  }


                                //查询库存信息
                               /*  $storageManageInfo = StorageManageModel:: where(['id' => $number_info['storage_manage_id'],'delete_flag' =>0])->first(); */

                                if (empty($storageManageInfo)) {
                                    return [
                                        'code' => 1,
                                        'msg' => '套餐内商品无库存信息，无法完成出库',
                                        'data' => ''
                                    ];
                                }

                                if($storageManageInfo['in_storage_num'] < ($value['num'] * $content['num'])) {
                                    return [
                                        'code' => 1,
                                        'msg' => '套餐内商品库存数不足，无法完成出库',
                                        'data' => ''
                                    ];
                                }

                                StorageManageModel::where('id', $storageManageInfo['id'])
                                    ->decrement('in_storage_num', $value['num']*$content['num']);

                                $prepareInfo = SellPackagePrepareOutLogModel::where('sell_id', $id)
                                    ->where('package_id', $value['package_id'])->first();

                                if(empty($prepareInfo)) {
                                    StorageManageModel::where('id', $storageManageInfo['id'])
                                        ->decrement('virtual_storage_num', $value['num'] * $content['num']);
                                }

                                LogPackageContentModel::insert([
                                    'log_package_id' => $logpackageNewId,
                                    'package_id' => $value['package_id'],
                                    'storage_id' => $storageManageInfo['id'],
                                    'storage_name' => $storageManageInfo['storage_name'],
                                    'storage_address' => $storageManageInfo['storage_address'],
                                    'materiel_class_id' => $storageManageInfo['materiel_class_id'],
                                    'materiel_class_name' => $storageManageInfo['materiel_class_name'],
                                    'materiel_class_no' => $storageManageInfo['materiel_class_no'],
                                    'materiel_type_id' => $storageManageInfo['type_id'],
                                    'materiel_name' => $storageManageInfo['materiel_name'],
                                    'type_name' => $storageManageInfo['type_name'],
                                    'materiel_no' => $storageManageInfo['materiel_no'],
                                    'operate_num' => $value['num'] * $content['num'],
                                    'out_storage_manage_id' => $storageManageInfo['id'],
                                    'last_storage_num' => $storageManageInfo['in_storage_num'],
                                    'next_storage_num' => $storageManageInfo['in_storage_num'] - ($value['num'] * $content['num']),
                                    'all_id_type' => 4,
                                    'all_id' => $id,
                                    'user_id' => $data['user_id'],
                                    'main_id' => $data['main_id'],
                                    'created_at' => time(),

                                    'shelf_id' =>$storageManageInfo['shelf_id'],
                                    'location_id' =>$storageManageInfo['location_id'],

                                ]);

                                $sellGoodsList[] = [
                                    'materiel_type_id' => $storageManageInfo['type_id'],
                                    'cost_price' => $storageManageInfo['materiel_mean_cost'],
                                    'num' => $value['num'] * $content['num'],
                                    'main_id' => $data['main_id'],
                                    'user_id' => $data['user_id'],
                                    'sell_id' => $id,
                                    'sell_date' => strtotime($sellInfo['sell_date']),
                                    'created_at' => time(),
                                ];

                                $sellOutStoragePackageContent = SellOutStoragePackageContentModel::where([
                                    'o_s_package_id' => $sellOutStoragePackageId,
                                    'type_id' => $storageManageInfo['type_id'],
                                    'storage_id' => $storageManageInfo['storage_id'],
                                    'shelf_id' => $storageManageInfo['shelf_id'],
                                    'location_id' => $storageManageInfo['location_id'],
                                ])->first();
                                if (empty($sellOutStoragePackageContent)) {
                                    SellOutStoragePackageContentModel::insert([
                                        'type_id' => $storageManageInfo['type_id'],
                                        'storage_id' => $storageManageInfo['storage_id'],
                                        'package_content_id' => $content['package_content_id'],
                                        'storage_manage_id' => $storageManageInfo['id'],
                                        'o_s_package_id' => $sellOutStoragePackageId,
                                        'sell_id' => $id,
                                        'num' => $value['num'] * $content['num'],
                                        'user_id' => $data['user_id'],
                                        'main_id' => $data['main_id'],
                                        'created_at' => time(),

                                        'shelf_id' => $storageManageInfo['shelf_id'],
                                        'location_id' => $storageManageInfo['location_id'],

                                    ]);
                                } else {
                                    SellOutStoragePackageContentModel::where('id', $sellOutStoragePackageContent['id'])
                                        ->increment('num', $value['num'] * $storageManageInfo['num']);
                                }
                    }

                    SellPackageDetailModel::where('sell_id', $id)
                        ->where('package_id', $value['package_id'])
                        ->increment('out_num', $value['num']);
                }

                SellGoodsListModel::insert($sellGoodsList);
            }

            $flag = 0;
            $sellGoodsSetailInfo = SellGoodsDetailModel::where('sell_id', $id)->get()->toArray();

            foreach($sellGoodsSetailInfo as $v1) {
                if($v1['num'] == $v1['out_num']) {
                    $flag = 1;
                }
                else {
                    $flag = 0;
                }
            }

            $sellPackageDetailInfo = SellPackageDetailModel::where('sell_id', $id)->get()->toArray();

            foreach($sellPackageDetailInfo as $v2) {
                if($v2['num'] == $v2['out_num']) {
                    $flag = 1;
                }
                else {
                    $flag = 0;
                }
            }

            if($flag) {
                SellModel::where('id',$id)->update(['out_status'=>2,'prepare_out_status' => 0]);//全部完成更新状态
                CheckModel::where(['main_id'=>$data['main_id'],'type'=>2,'all_id'=>$id])
                    ->update(['status'=>1,'out_in_status'=>0]);
                ProductOrderModel::where([
                    'product_source' => 1,
                    'product_source_id' => $id
                ])
                    ->update(['product_status' => 2]);
            }
            else {
                CheckModel::where(['main_id'=>$data['main_id'],'type'=>2,'all_id'=>$id])
                    ->update(['out_in_status'=>1]);

                ProductOrderModel::where([
                    'product_source' => 1,
                    'product_source_id' => $id
                ])
                    ->update(['product_status' => 1]);
            }

            if(!empty($productContentStorageData)) {
                $checkProductOrderInfo = ProductOrderModel::where([
                    'product_source' => 1,
                    'product_source_id' => $id
                ])->first();

                if(!empty($checkProductOrderInfo)) {
                    foreach($productContentStorageData as $vvv) {
                        ProductSlaveContentStorageModel::where([
                            'type_id' => $vvv['type_id'],
                            'serial_id' => $vvv['serial_id'],
                            'product_order_id' => $checkProductOrderInfo['id']
                        ])->increment('storage_operate_num');
                    }
                }
            }

            //插入序列号关联表
           /*  $serial = implode(',',$serial_array);
            DB::table('sell_out_serial_numbers')->insert([
                ['main_id' =>  $data['main_id'], 'created_at' => time(), 'sell_id' => $data['id'], 'serial_number' => $serial, 'status' => 1],
            ]); */

            DB::commit();
            return ['code' => 0, 'msg' => 'success', 'data' => ''];
        }
        catch(\Exception $e) {
            DB::rollBack();
            Log::debug('销售单出库:'.var_export($e->getMessage(),true));
            return ['code' => 1, 'msg' => $e->getMessage(), 'data' => ''];
        }

    }

    static private function sellMaterielPart($paramsArr, $id, $key, $data, $goodsData)
    {
        DB::beginTransaction();

        try {
            $storageInfo = StorageModel::where('id', $goodsData['warehouse_id'])->first();
            $materielTypeInfo = MaterielsTypeModel::where('id', $goodsData['materiel_type_id'])->first();

            //销售单商品出库记录
            $sellOutStorageInfo = SellOutStorageModel::where([
                'materiel_type_id' => $goodsData['materiel_type_id'],
                'sell_id' => $id,
                'shelf_id' => $goodsData['shelf_id'],
                'location_id' => $goodsData['location_id'],
            ])->first();

            //销售单商品信息
            $sellGoodsDetailInfo = SellGoodsDetailModel::where([
                'materiel_type_id' => $goodsData['materiel_type_id'],
                'sell_id' => $id,
                'shelf_id' => $goodsData['shelf_id'],
                'location_id' => $goodsData['location_id'],
            ])->first();

            //验证是否已经出库
            if(empty($sellOutStorageInfo)) {
                $datavalue = [];
                if($sellGoodsDetailInfo['num'] < $goodsData['num']) {
                    return [
                        'code' => 1,
                        'msg' => '超出商品最大可出库数量，商品:'.$materielTypeInfo['materiel_name'].'-'.$materielTypeInfo['type_name'].'最大可出库数量为:'.$sellGoodsDetailInfo['num'],
                        'data' => ''
                    ];
                }

                $datavalue['sell_id'] = $id;
                $datavalue['name'] = $materielTypeInfo['materiel_name'];
                $datavalue['type_name'] = $materielTypeInfo['type_name'];
                $datavalue['num'] = $goodsData['num'];
                $datavalue['price'] = $goodsData['price'];
                $datavalue['warehouse'] = $storageInfo['storage_name'];
                $datavalue['warehouse_id'] = $storageInfo['id'];
                $datavalue['materiel_type_id'] = $materielTypeInfo['id'];
                $datavalue['remark'] = empty($goodsData['remark'])?'':$goodsData['remark'];

                $datavalue['shelf_id'] = $goodsData['shelf_id'];
                $datavalue['location_id'] = $goodsData['location_id'];

                SellOutStorageModel::insert($datavalue);
            }
            else {
                if($goodsData['num'] > $sellGoodsDetailInfo['num'] - $sellGoodsDetailInfo['out_num']) {
                    return [
                        'code' => 1,
                        'msg' => '超出商品最大可出库数量，商品:'.$materielTypeInfo['materiel_name'].'-'.$materielTypeInfo['type_name'].'最大可出库数量为:'.($sellGoodsDetailInfo['num'] - $sellGoodsDetailInfo['out_num']),
                        'data' => ''
                    ];
                }

                SellOutStorageModel::where('id', $sellOutStorageInfo['id'])
                    ->increment('num', $goodsData['num'], [
                        'remark' => $goodsData['remark']
                    ]);
            }

                //更新销售单商品信息已出库数量
                SellGoodsDetailModel::where('id', $sellGoodsDetailInfo['id'])
                    ->increment('out_num', $goodsData['num']);
                $paramsArr['content'][$key]['num'] = $goodsData['num'];

            $paramsArr['content'][$key]['name'] = $materielTypeInfo['materiel_name'];
            $paramsArr['content'][$key]['price'] = $goodsData['price'];
            $paramsArr['content'][$key]['type_name'] = $materielTypeInfo['type_name'];
            $paramsArr['content'][$key]['warehouse'] = $storageInfo['storage_name'];
            $paramsArr['content'][$key]['warehouse_id'] = $storageInfo['id'];

            $paramsArr['content'][$key]['shelf_id'] = $goodsData['shelf_id'];
            $paramsArr['content'][$key]['location_id'] = $goodsData['location_id'];

            DB::commit();
            return $paramsArr;
        } catch (\Exception $e) {
            DB::rollBack();
            Log::debug('销售单部分出库-商品:'.var_export($e->getMessage(),true));
            return ['code' => 1, 'msg' => $e->getMessage(), 'data' => ''];
        }
    }

    //使用批次时套餐出库
    static public function sellPackagePartWithBatch($id, $goods, $data, $value)
    {
        DB::beginTransaction();

        try {
            $SellPackageDetailInfo = SellPackageDetailModel::select(
                'a.*',
                'b.package_name'
            )
                ->from('sell_package_detail as a')
                ->leftJoin('package as b', 'b.id', '=', 'a.package_id')
                ->where([
                    'sell_id' => $data['id'],
                    'a.package_id' => $value['package_id'],
                    'a.main_id' => $data['main_id'],
                ])->first();

            if (empty($SellPackageDetailInfo)) {
                return [
                    'code' => 1,
                    'msg' => '销售单内指定的套餐不存在，无法出库',
                    'data' => ''
                ];
            }

            if(($SellPackageDetailInfo['num'] - $SellPackageDetailInfo['out_num']) < $value['num']) {
                return [
                    'code' => 1,
                    'msg' => '套餐:'.$SellPackageDetailInfo['package_name'].'超出可出库套餐数',
                    'data' => ''
                ];
            }

            $batchOutInfo = [];
            $packageContentNeedNum = 0;
            //遍历套餐内容信息
            foreach($value['package_content'] as $v1) {
                //套餐商品内容信息
                $packageContentInfo = SellPackageContentModel::where('id', $v1['package_content_id'])->first();
                //套餐内容所需总数量
                $packageContentNeedNum = $value['num'] * $packageContentInfo['num'];

                //销售单内单商品所有批次总数
                $batchTotalNum = 0;
                foreach($v1['batch_info'] as $v2) {
                    $storageBatchInfo = StorageBatchModel::where('id', $v2['batch_id'])->first();

                    if($storageBatchInfo['batch_left_num'] < $packageContentNeedNum) {
                        return [
                            'code' => 1,
                            'msg' => '套餐内商品存在批次库存数量不足的情况，无法完成出库',
                            'data' => ''
                        ];
                    }

                    $batchOutInfo[] = [
                        'batch_id' => $v2['batch_id'],
                        'num' => $v2['num'],
                        'sell_package_content_id' => $v1['package_content_id'],
                        'storage_manage_id' => $v2['storage_manage_id']
                    ];
                }
            }

            foreach($batchOutInfo as $kk => $v3) {
                StorageManageModel::where('id', $v3['storage_manage_id'])
                    ->decrement('in_storage_num', $v3['num']);

                StorageBatchModel::where('id', $v3['batch_id'])
                    ->decrement('batch_left_num', $v3['num']);

                SellPackageBatchModel::where('sell_package_content_id', $v3['sell_package_content_id'])
                    ->where('sell_id', $id)
                    ->decrement('rest_num', $v3['num']);

                $packageInfo = SellPackageContentModel::where([
                    'package_id' => $value['package_id'],
                    'sell_id' => $id
                ])->first();

                $logOutPackageArr[$kk]['package_id'] = $value['package_id'];
                $logOutPackageArr[$kk]['out_time'] = strtotime(date('Y-m-d'));
                $logOutPackageArr[$kk]['mean_cost'] = empty($packageInfo['total_cost'])?0:$packageInfo['total_cost'];
                $logOutPackageArr[$kk]['num'] = $value['num'];
                $logOutPackageArr[$kk]['price'] = $value['price'];
                $logOutPackageArr[$kk]['all_id_type'] = 2;
                $logOutPackageArr[$kk]['all_id'] = $id;
                $logOutPackageArr[$kk]['user_id'] = $data['user_id'];
                $logOutPackageArr[$kk]['main_id'] = $data['main_id'];
                $logOutPackageArr[$kk]['created_at'] = time();

                //出库套餐信息记录
                $logPackageArr['package_id'] = $value['package_id'];
                $logPackageArr['package_name'] = $SellPackageDetailInfo['package_name'];
                $logPackageArr['num'] = $value['num'];
                $logPackageArr['all_id_type'] = 2;
                $logPackageArr['all_id'] = $id;
                $logPackageArr['user_id'] = $data['user_id'];
                $logPackageArr['main_id'] = $data['main_id'];
                $logPackageArr['remark'] = empty($value['remark'])?'':$value['remark'];
                $logPackageArr['created_at'] = time();

                $logpackageNewId = LogPackageModel::insertGetId($logPackageArr);

                $storageManageInfo = StorageManageModel::select(
                    'a.id',
                    'a.type_id',
                    'b.type_name',
                    'b.materiel_name',
                    'b.materiel_no',
                    'a.materiel_class_id',
                    'c.class_name as materiel_class_name',
                    'c.class_no as materiel_class_no',
                    'a.storage_id',
                    'd.storage_name',
                    'd.storage_address',
                    'a.materiel_mean_cost',
                    'a.in_storage_num'
                )
                    ->from('storage_manage as a')
                    ->leftJoin('materiel_type as b', 'b.id', '=', 'a.type_id')
                    ->leftJoin('materiel_class as c', 'c.id', '=', 'a.materiel_class_id')
                    ->leftJoin('storage as d', 'd.id', '=', 'a.storage_id')
                    ->where([
                        'a.id' => $v3['storage_manage_id'],
                        'a.delete_flag' => 0,
                        'a.main_id' => $data['main_id']
                    ])
                    ->first();

                if(empty($storageManageInfo)) {
                    return [
                        'code' => 1,
                        'msg' => '库存不存在，无法出库',
                        'data' => ''
                    ];
                }

                LogPackageContentModel::insert([
                    'log_package_id' => $logpackageNewId,
                    'package_id' => $value['package_id'],
                    'storage_id' => $storageManageInfo['storage_id'],
                    'storage_name' => $storageManageInfo['storage_name'],
                    'storage_address' => $storageManageInfo['storage_address'],
                    'materiel_class_id' => $storageManageInfo['materiel_class_id'],
                    'materiel_class_name' => $storageManageInfo['materiel_class_name'],
                    'materiel_class_no' => $storageManageInfo['materiel_class_no'],
                    'materiel_type_id' => $storageManageInfo['type_id'],
                    'materiel_name' => $storageManageInfo['materiel_name'],
                    'type_name' => $storageManageInfo['type_name'],
                    'materiel_no' => $storageManageInfo['materiel_no'],
                    'operate_num' => $v3['num'],
                    'out_storage_manage_id' => $storageManageInfo['id'],
                    'storage_batch_id' => $v3['batch_id'],
                    'last_storage_num' => $storageManageInfo['in_storage_num'],
                    'next_storage_num' => $storageManageInfo['in_storage_num'] - ($v3['num']),
                    'all_id_type' => 4,
                    'all_id' => $id,
                    'user_id' => $data['user_id'],
                    'main_id' => $data['main_id'],
                    'created_at' => time()
                ]);

                $sellOutStoragePackage = SellOutStoragePackageModel::where([
                    'package_id' => $value['package_id'],
                    'sell_id' => $id
                ])->first();

                if (empty($sellOutStoragePackage)) {
                    $newId = SellOutStoragePackageModel::insertGetId([
                        'package_id' => $value['package_id'],
                        'price' => $value['price'],
                        'num' => $value['num'],
                        'remark' => empty($value['remark'])?'':$value['remark'],
                        'sell_id' => $id
                    ]);

                    SellOutStoragePackageContentModel::insert([
                        'type_id' => $storageManageInfo['type_id'],
                        'storage_id' => $storageManageInfo['storage_id'],
                        'package_content_id' => $v1['package_content_id'],
                        'storage_manage_id' => $v3['storage_manage_id'],
                        'o_s_package_id' => $newId,
                        'sell_id' => $id,
                        'num' => $packageContentNeedNum,
                        'user_id' => $data['user_id'],
                        'main_id' => $data['main_id'],
                        'created_at' => time()
                    ]);
                } else {
                    SellOutStoragePackageModel::where('id', $sellOutStoragePackage['id'])
                        ->increment('num', $value['num']);

                    SellOutStoragePackageContentModel::where('o_s_package_id', $sellOutStoragePackage['id'])
                        ->increment('num', $packageContentNeedNum);
                }
            }

            LogOutPackageModel::insert($logOutPackageArr);
            SellPackageDetailModel::where('sell_id', $id)
                ->where('package_id', $value['package_id'])
                ->increment('out_num', $value['num']);

            DB::commit();
            return true;
        }
        catch(\Exception $e) {
            DB::rollBack();
            Log::debug('销售单部分出库-套餐:'.var_export($e->getMessage(),true));
            return ['code' => 1, 'msg' => $e->getMessage(), 'data' => ''];
        }
    }

    static public function sellPackagePart($id, $packageInfo, $data)
    {
        $sellInfo = SellModel::where('id', $id)->first();
        DB::beginTransaction();

        try {
            $logOutPackageArr = [];
            $sellGoodsList = [];
            foreach($packageInfo as $value) {
                $SellPackageDetailInfo = SellPackageDetailModel::select(
                    'a.*',
                    'b.package_name'
                )
                    ->from('sell_package_detail as a')
                    ->leftJoin('package as b', 'b.id', '=', 'a.package_id')
                    ->where([
                        'sell_id' => $data['id'],
                        'a.package_id' => $value['package_id'],
                        'a.main_id' => $data['main_id'],
                    ])->first()->toArray();

                if (empty($SellPackageDetailInfo)) {
                    return [
                        'code' => 1,
                        'msg' => '销售单内指定的套餐不存在，无法出库',
                        'data' => ''
                    ];
                }

                if ($value['num'] > ($SellPackageDetailInfo['num'] - $SellPackageDetailInfo['out_num'])) {
                    return [
                        'code' => 1,
                        'msg' => '套餐可出库数量不足',
                        'data' => ''
                    ];
                }

                $logpackageNewId = LogPackageModel::insertGetId([
                    'package_id' => $value['package_id'],
                    'package_name' => $SellPackageDetailInfo['package_name'],
                    'num' => $SellPackageDetailInfo['num'],
                    'sell_price' => $value['price'],
                    'cost' => sprintf('%.6f', self::getPackageCost($id, $value['package_id']) * $SellPackageDetailInfo['num']),
                    'out_storage_time' => strtotime($data['in_storage_time']),
                    'all_id_type' => 2,
                    'all_id' => $id,
                    'user_id' => $data['user_id'],
                    'main_id' => $data['main_id'],
                    'remark' => empty($value['remark'])?'':$value['remark'],
                    'created_at' => time(),
                ]);

                $sellPackageContentInfo = SellPackageContentModel::where([
                    'package_detail_id' => $SellPackageDetailInfo['id']
                ])->get()->toArray();

                $sellOutStoragePackage = SellOutStoragePackageModel::where([
                    'package_id' => $value['package_id'],
                    'sell_id' => $id
                ])->first();

                if (empty($sellOutStoragePackage)) {
                    $sellOutStoragePackageId = SellOutStoragePackageModel::insertGetId([
                        'package_id' => $value['package_id'],
                        'price' => $SellPackageDetailInfo['price'],
                        'num' => $value['num'],
                        'remark' => empty($value['remark'])?'':$value['remark'],
                        'sell_id' => $id
                    ]);

                } else {
                    $sellOutStoragePackageId = $sellOutStoragePackage['id'];

                    SellOutStoragePackageModel::where('id', $sellOutStoragePackage['id'])
                        ->increment('num', $value['num']);
                }

                foreach ($sellPackageContentInfo as $kk => $val) {
                    $storageManageInfo = StorageManageModel::select(
                        'a.id',
                        'a.type_id',
                        'b.type_name',
                        'b.materiel_name',
                        'b.materiel_no',
                        'a.materiel_class_id',
                        'c.class_name as materiel_class_name',
                        'c.class_no as materiel_class_no',
                        'a.storage_id',
                        'd.storage_name',
                        'd.storage_address',
                        'a.materiel_mean_cost',
                        'a.in_storage_num',
                        'alert_num',
                        'a.materiel_mean_cost',
                        'a.shelf_id',
                        'a.location_id',
                    )
                        ->from('storage_manage as a')
                        ->leftJoin('materiel_type as b', 'b.id', '=', 'a.type_id')
                        ->leftJoin('materiel_class as c', 'c.id', '=', 'a.materiel_class_id')
                        ->leftJoin('storage as d', 'd.id', '=', 'a.storage_id')
                        ->where([
                            'a.id' => $val['storage_manage_id'],
                            'a.delete_flag' => 0,
                            'a.main_id' => $data['main_id']
                        ])
                        ->first();

                    if (empty($storageManageInfo)) {
                        return [
                            'code' => 1,
                            'msg' => '套餐内商品无库存信息，无法完成出库',
                            'data' => ''
                        ];
                    }

                    if($storageManageInfo['in_storage_num'] < ($value['num'] * $val['num'])) {
                        return [
                            'code' => 1,
                            'msg' => '套餐内商品库存数不足，无法完成出库',
                            'data' => ''
                        ];
                    }

                    StorageManageModel::where('id', $val['storage_manage_id'])
                        ->decrement('in_storage_num', $value['num'] * $val['num']);

                    $prepareInfo = SellPackagePrepareOutLogModel::where('sell_id', $id)
                        ->where('package_id', $value['package_id'])->first();

                    if(empty($prepareInfo)) {
                        StorageManageModel::where('id', $storageManageInfo['id'])
                            ->decrement('virtual_storage_num', $value['num'] * $val['num']);
                    }

                    LogPackageContentModel::insert([
                        'log_package_id' => $logpackageNewId,
                        'package_id' => $value['package_id'],
                        'storage_id' => $val['storage_id'],
                        'storage_name' => $storageManageInfo['storage_name'],
                        'storage_address' => $storageManageInfo['storage_address'],
                        'materiel_class_id' => $storageManageInfo['materiel_class_id'],
                        'materiel_class_name' => $storageManageInfo['materiel_class_name'],
                        'materiel_class_no' => $storageManageInfo['materiel_class_no'],
                        'materiel_type_id' => $storageManageInfo['type_id'],
                        'materiel_name' => $storageManageInfo['materiel_name'],
                        'type_name' => $storageManageInfo['type_name'],
                        'materiel_no' => $storageManageInfo['materiel_no'],
                        'operate_num' => $value['num'] * $val['num'],
                        'out_storage_manage_id' => $storageManageInfo['id'],
                        'last_storage_num' => $storageManageInfo['in_storage_num'],
                        'next_storage_num' => $storageManageInfo['in_storage_num'] - ($value['num'] * $val['num']),
                        'all_id_type' => 4,
                        'all_id' => $id,
                        'user_id' => $data['user_id'],
                        'main_id' => $data['main_id'],
                        'created_at' => time(),

                        'shelf_id' =>$val['shelf_id'],
                        'location_id' =>$val['location_id'],

                    ]);

                    $sellGoodsList[] = [
                        'materiel_type_id' => $storageManageInfo['type_id'],
                        'cost_price' => $storageManageInfo['materiel_mean_cost'],
                        'num' => $value['num'] * $val['num'],
                        'main_id' => $data['main_id'],
                        'user_id' => $data['user_id'],
//                        'sell_id' => $data['all_id'],
                        'sell_id' => $id,
                        'sell_date' => strtotime($sellInfo['sell_date']),
                        'created_at' => time(),
                    ];

                    $sellOutStoragePackageContent = SellOutStoragePackageContentModel::where([
                        'o_s_package_id' => $sellOutStoragePackageId,
                        'type_id' => $storageManageInfo['type_id'],
                        'storage_id' => $val['storage_id'],
                        'shelf_id' => $val['shelf_id'],
                        'location_id' => $val['location_id'],
                    ])->first();

                    if (empty($sellOutStoragePackageContent)) {
                        SellOutStoragePackageContentModel::insert([
                            'type_id' => $storageManageInfo['type_id'],
                            'storage_id' => $val['storage_id'],
                            'package_content_id' => $val['package_content_id'],
                            'storage_manage_id' => $val['storage_manage_id'],
                            'o_s_package_id' => $sellOutStoragePackageId,
                            'sell_id' => $id,
                            'num' => $value['num'] * $val['num'],
                            'user_id' => $data['user_id'],
                            'main_id' => $data['main_id'],
                            'created_at' => time(),

                            'shelf_id' => $val['shelf_id'],
                            'location_id' => $val['location_id'],

                        ]);
                    } else {
                        SellOutStoragePackageContentModel::where('id', $sellOutStoragePackageContent['id'])
                            ->increment('num', $value['num'] * $val['num']);
                    }
                }

                SellPackageDetailModel::where('sell_id', $id)
                    ->where('package_id', $value['package_id'])
                    ->increment('out_num', $value['num']);
            }

            SellGoodsListModel::insert($sellGoodsList);
//            LogOutPackageModel::insert($logOutPackageArr);
            DB::commit();
            return true;
        }
        catch(\Exception $e) {
            DB::rollBack();
            Log::debug('销售单部分出库-套餐:'.var_export($e->getMessage(),true));
            return ['code' => 1, 'msg' => $e->getMessage(), 'data' => ''];
        }
    }

    //获取套餐总成本
    static public function getPackageCost($sellId, $packageId)
    {
        $data = SellPackageContentModel::select(
            DB::raw('SUM(num * cost) as total_cost')
        )
            ->from('sell_package_content as a')
            ->leftJoin('materiel_type as b', 'b.id', '=', 'a.materiel_type_id')
            ->where('sell_id', $sellId)
            ->where('package_id', $packageId)
            ->groupBy('package_id')
            ->first();

        return $data['total_cost'];
    }

    //全部出库
    static public function allSell($paramsArr, $id, $goods, $package, $data)
    {
        DB::enableQueryLog();

        try {
            //更新销售入库状态
            SellModel::where('id',$id)->update(['out_status'=>1]);

            $paramsArr['all_id'] = $id;
            isset($data['remark'])?$paramsArr['remark'] = $data['remark']:$paramsArr['remark'] = '';
            $paramsArr['all_id_type'] = 2;//销售退货均为2
            $paramsArr['out_storage_time'] = $data['in_storage_time'];

            if(!empty($goods)) {
                //部分出库临时存储
                $goodsInfo = json_decode($goods,true);

                foreach($goodsInfo as $key => $value) {
                    $paramsArr = self::sellMaterielAll($paramsArr, $id, $key, $data, $value);

                    if(isset($paramsArr['code'])) {
                        return $paramsArr;
                    }
                }
            }

            if(!empty($package)) {
                //部分出库临时存储
                $packageInfo = json_decode($package,true);

                foreach($packageInfo as $key => $value) {
//                    if($data['out_way']) {
//                        $packageOutInfo = self::sellPackageAllWithBatch($id, $goods, $data, $value);
//                    }
//                    else {
                        $packageOutInfo = self::sellPackageAll($id, $goods, $data, $value);
//                    }

                    if(isset($packageOutInfo['code'])) {
                        return $packageOutInfo;
                    }
                }
            }

            //调用出库
            if(isset($paramsArr['content'])) {
                $res = StorageManageService::outStorage($data['user_id'], $data['main_id'], $paramsArr, $id);
                if($res['code']){
                    return $res;
                }
            }

            SellModel::where('id',$id)->update(['out_status'=>2]);//全部完成更新状态
            CheckModel::where(['main_id'=>$data['main_id'],'type'=>2,'all_id'=>$id])->update(['status'=>1,'out_in_status'=>0]);

            DB::commit();
            return ['code' => 0, 'msg' => 'success', 'data' => ''];
        }
        catch(\Exception $e) {
            DB::rollBack();
            Log::debug('销售单全部出库'.var_export($e->getMessage(), true));
            return ['code' => 1, 'msg' => $e->getMessage(), 'data' => ''];
        }
    }

    static private function sellMaterielAll($paramsArr, $id, $key, $data, $value)
    {
        DB::beginTransaction();
        try {
            $sellGoodsDetailInfo = SellGoodsDetailModel::where([
                'materiel_type_id' => $value['materiel_type_id'],
                'sell_id' => $id
            ])->first();

            $leftNum = $sellGoodsDetailInfo['num'] - $sellGoodsDetailInfo['out_num'];

            if($sellGoodsDetailInfo['num'] > $sellGoodsDetailInfo['out_num']) {
                if(!$data['out_way']) {
                    $storageInfo = StorageModel::where('id', $value['warehouse_id'])->first();
                    @$materielTypeInfo = MaterielsTypeModel::where('id', $value['materiel_type_id'])->first()->toArray();

                    $paramsArr['content'][$key]['name'] = $materielTypeInfo['materiel_name'];
                    $paramsArr['content'][$key]['price'] = $value['price'];
                    $paramsArr['content'][$key]['type_name'] = $materielTypeInfo['type_name'];
                    $paramsArr['content'][$key]['num'] = $leftNum;
                    $paramsArr['content'][$key]['warehouse'] = $storageInfo['storage_name'];
                    $paramsArr['content'][$key]['warehouse_id'] = $storageInfo['id'];
                    $paramsArr['content'][$key]['remark'] = empty($value['remark'])?'':$value['remark'];

                    $datavalue['sell_id'] = $id;
                    $datavalue['name'] = $materielTypeInfo['materiel_name'];
                    $datavalue['type_name'] = $materielTypeInfo['type_name'];
                    $datavalue['num'] = $leftNum;
                    $datavalue['price'] = $value['price'];
                    $datavalue['warehouse'] = $storageInfo['storage_name'];
                    $datavalue['warehouse_id'] = $storageInfo['id'];
                    $datavalue['materiel_type_id'] = $materielTypeInfo['id'];
                    $datavalue['remark'] = empty($value['remark'])?'':$value['remark'];

                    SellOutStorageModel::insert($datavalue);

                    SellGoodsDetailModel::where([
                        'materiel_type_id' => $value['materiel_type_id'],
                        'sell_id' => $id
                    ])->increment('out_num', $leftNum);
                }
                else {
                    $leftSellGoodsBatch = SellGoodsDetailBatchModel::where('sell_id', $id)
                        ->where('rest_num', '>', 0)->get();

                    foreacH($leftSellGoodsBatch as $key => $vals) {
                        $storageManageInfo = StorageManageModel::select(
                            'a.id',
                            'c.materiel_name',
                            'c.type_name',
                            'b.id as storage_id',
                            'b.storage_name',
                        )
                            ->from('storage_manage as a')
                            ->leftJoin('storage as b', 'b.id', '=', 'a.storage_id')
                            ->leftJoin('materiel_type as c', 'c.id', '=', 'a.type_id')
                            ->where('a.id', $vals['storage_manage_id'])
                            ->first();

                        $paramsArr['content'][$key]['name'] = $storageManageInfo['materiel_name'];
                        $paramsArr['content'][$key]['price'] = $value['price'];
                        $paramsArr['content'][$key]['type_name'] = $storageManageInfo['type_name'];
                        $paramsArr['content'][$key]['num'] = $leftNum;
                        $paramsArr['content'][$key]['warehouse'] = $storageManageInfo['storage_name'];
                        $paramsArr['content'][$key]['warehouse_id'] = $storageManageInfo['storage_id'];
                        $paramsArr['content'][$key]['remark'] = empty($value['remark'])?'':$value['remark'];

                        SellGoodsDetailModel::where([
                            'id' => $vals['sell_goods_detail_id'],
                            'sell_id' => $id
                        ])->increment('out_num', $leftNum);

                        SellGoodsDetailBatchModel::where('id', $vals['id'])
                            ->decrement('rest_num', $vals['num']);
                    }
                }
            }

            DB::commit();
            return $paramsArr;
        }
        catch(\Exception $e) {
            DB::rollBack();
            Log::debug('销售单全部出库-商品'.var_export($e->getMessage(), true));
            return ['code' => 1, 'msg' => $e->getMessage(), 'data' => ''];
        }
    }

    static private function sellPackageAllWithBatch($id, $goods, $data, $value)
    {
        DB::beginTransaction();

        try {
            $sellPackageBatchInfo = SellPackageBatchModel::select(
                'a.id',
                'sell_package_content_id',
                'a.storage_manage_id',
                'a.num',
                'a.rest_num',
                'd.package_name',
                'e.storage_id'
            )
                ->from('sell_package_batch as a')
                ->leftJoin('sell_package_content as b', 'b.id', '=', 'a.sell_package_content_id')
                ->leftJoin('sell_package_detail as c', 'c.id', '=', 'b.package_detail_id')
                ->leftJoin('package as d', 'd.id', '=', 'c.package_id')
                ->leftJoin('storage_manage as e', 'e.id', '=', 'a.storage_manage_id')
                ->where('a.sell_id', $id)
                ->where('rest_num', '>', 0)
                ->get()->toArray();

            if(!empty($sellPackageBatchInfo)) {
                foreach ($sellPackageBatchInfo as $kk => $val) {
                    SellPackageBatchModel::where('id', $val['id'])->decrement('rest_num', $val['rest_num']);
                    $storageManageInfo = StorageManageModel::select(
                        'a.id',
                        'a.type_id',
                        'b.type_name',
                        'b.materiel_name',
                        'b.materiel_no',
                        'a.materiel_class_id',
                        'c.class_name as materiel_class_name',
                        'c.class_no as materiel_class_no',
                        'a.storage_id',
                        'd.storage_name',
                        'd.storage_address',
                        'a.materiel_mean_cost',
                        'a.in_storage_num',
                        'a.virtual_storage_num'
                    )
                        ->from('storage_manage as a')
                        ->leftJoin('materiel_type as b', 'b.id', '=', 'a.type_id')
                        ->leftJoin('materiel_class as c', 'c.id', '=', 'a.materiel_class_id')
                        ->leftJoin('storage as d', 'd.id', '=', 'a.storage_id')
                        ->where([
                            'a.id' => $val['storage_manage_id'],
                            'a.delete_flag' => 0,
                            'a.main_id' => $data['main_id']
                        ])
                        ->first();

                    if (empty($storageManageInfo)) {
                        return [
                            'code' => 1,
                            'msg' => '套餐内商品无库存信息，无法完成出库',
                            'data' => ''
                        ];
                    }

                    if ($storageManageInfo['in_storage_num'] < ($val['rest_num'])) {
                        return [
                            'code' => 1,
                            'msg' => '套餐内商品库存不足，无法完成出库',
                            'data' => ''
                        ];
                    }

                    StorageManageModel::where('id', $val['storage_manage_id'])
                        ->decrement('in_storage_num', $val['rest_num']);

                    $prepareInfo = SellPackagePrepareOutLogModel::where('sell_id', $id)
                        ->where('package_id', $value['package_id'])->first();

                    if(empty($prepareInfo)) {
                        if($storageManageInfo['virtual_storage_num'] < $val['rest_num']) {
                            return ['code' => 1, 'msg' => '库存不足无法操作出库', 'data' => ''];
                        }
                        StorageManageModel::where('id', $storageManageInfo['id'])
                            ->decrement('virtual_storage_num', $val['rest_num']);
                    }

                    $SellPackageDetailInfo = SellPackageDetailModel::where('package_id', $value['package_id'])
                        ->where('sell_id', $id)->first();

                    //销售单成本表
                    $logOutPackageArr[$kk]['package_id'] = $value['package_id'];
                    $logOutPackageArr[$kk]['out_time'] = strtotime(date('Y-m-d'));
                    $logOutPackageArr[$kk]['mean_cost'] = $storageManageInfo['materiel_mean_cost'];
                    $logOutPackageArr[$kk]['num'] = $val['rest_num'];
                    $logOutPackageArr[$kk]['price'] = $SellPackageDetailInfo['price'];
                    $logOutPackageArr[$kk]['all_id_type'] = 2;
                    $logOutPackageArr[$kk]['all_id'] = $id;
                    $logOutPackageArr[$kk]['user_id'] = $data['user_id'];
                    $logOutPackageArr[$kk]['main_id'] = $data['main_id'];
                    $logOutPackageArr[$kk]['created_at'] = time();

                    //出库套餐信息记录
                    $logPackageArr['package_id'] = $value['package_id'];
                    $logPackageArr['package_name'] = $val['package_name'];
                    $logPackageArr['num'] = $val['rest_num'];
                    $logPackageArr['all_id_type'] = 2;
                    $logPackageArr['all_id'] = $id;
                    $logPackageArr['user_id'] = $data['user_id'];
                    $logPackageArr['main_id'] = $data['main_id'];
                    $logPackageArr['remark'] = $value['remark'];
                    $logPackageArr['created_at'] = time();

                    $logpackageNewId = LogPackageModel::insertGetId($logPackageArr);

                    LogPackageContentModel::insert([
                        'log_package_id' => $logpackageNewId,
                        'package_id' => $value['package_id'],
                        'storage_id' => $val['storage_id'],
                        'storage_name' => $storageManageInfo['storage_name'],
                        'storage_address' => $storageManageInfo['storage_address'],
                        'materiel_class_id' => $storageManageInfo['materiel_class_id'],
                        'materiel_class_name' => $storageManageInfo['materiel_class_name'],
                        'materiel_class_no' => $storageManageInfo['materiel_class_no'],
                        'materiel_type_id' => $storageManageInfo['type_id'],
                        'materiel_name' => $storageManageInfo['materiel_name'],
                        'type_name' => $storageManageInfo['type_name'],
                        'materiel_no' => $storageManageInfo['materiel_no'],
                        'operate_num' => $val['rest_num'],
                        'storage_batch_id' => $val['id'],
                        'out_storage_manage_id' => $storageManageInfo['id'],
                        'last_storage_num' => $storageManageInfo['in_storage_num'],
                        'next_storage_num' => $storageManageInfo['in_storage_num'] - $val['rest_num'],
                        'all_id_type' => 4,
                        'all_id' => $id,
                        'user_id' => $data['user_id'],
                        'main_id' => $data['main_id'],
                        'created_at' => time()
                    ]);

                    $sellOutStoragePackage = SellOutStoragePackageModel::where([
                        'package_id' => $value['package_id'],
                        'sell_id' => $id
                    ])->first();

                    if (empty($sellOutStoragePackage)) {
                        $newId = SellOutStoragePackageModel::insertGetId([
                            'package_id' => $value['package_id'],
                            'price' => $SellPackageDetailInfo['price'],
                            'num' => $leftNum,
                            'sell_id' => $id,
                            'remark' => empty($value['remark'])?:$value['remark']
                        ]);

                        SellOutStoragePackageContentModel::insert([
                            'type_id' => $storageManageInfo['type_id'],
                            'storage_id' => $val['storage_id'],
                            'package_content_id' => $val['package_content_id'],
                            'storage_manage_id' => $val['storage_manage_id'],
                            'o_s_package_id' => $newId,
                            'sell_id' => $id,
                            'num' => $val['rest_num'],
                            'user_id' => $data['user_id'],
                            'main_id' => $data['main_id'],
                            'created_at' => time()
                        ]);
                    } else {
                        SellOutStoragePackageModel::where('id', $sellOutStoragePackage['id'])
                            ->increment('num', $val['rest_num'], [
                                'remark' => empty($value['remark'])?'':$value['remark']
                            ]);

                        SellOutStoragePackageContentModel::where('o_s_package_id', $sellOutStoragePackage['id'])
                            ->increment('num', $val['rest_num']);
                    }
                }

                LogOutPackageModel::insert($logOutPackageArr);
                SellPackageDetailModel::where('sell_id', $id)
                    ->where('package_id', $value['package_id'])
                    ->increment('out_num', $val['rest_num']);
            }
        }
        catch(\Exception $e) {
            DB::rollBack();
            Log::debug('销售单全部出库-商品'.var_export($e->getMessage(), true));
            return ['code' => 1, 'msg' => $e->getMessage(), 'data' => ''];
        }
    }

    static public function sellPackageAll($id, $goods, $data, $value)
    {
        DB::beginTransaction();

        try {
            $logOutPackageArr = [];
            $logPackageArr = [];

            $SellPackageDetailInfo = SellPackageDetailModel::select(
                'a.*',
                'b.package_name'
            )
                ->from('sell_package_detail as a')
                ->leftJoin('package as b', 'b.id', '=', 'a.package_id')
                ->where([
                    'sell_id' => $data['id'],
                    'a.package_id' => $value['package_id'],
                    'a.main_id' => $data['main_id'],
                ])
                ->whereRaw('num > out_num')
                ->first();

            if(!empty($SellPackageDetailInfo)) {
                //剩余未出库数量
                $leftNum = $SellPackageDetailInfo['num'] - $SellPackageDetailInfo['out_num'];

                $sellPackageContentInfo = SellPackageContentModel::where([
                    'package_detail_id' => $SellPackageDetailInfo['id']
                ])->get()->toArray();

                foreach ($sellPackageContentInfo as $kk => $val) {
                    $storageManageInfo = StorageManageModel::select(
                        'a.id',
                        'a.type_id',
                        'b.type_name',
                        'b.materiel_name',
                        'b.materiel_no',
                        'a.materiel_class_id',
                        'c.class_name as materiel_class_name',
                        'c.class_no as materiel_class_no',
                        'a.storage_id',
                        'd.storage_name',
                        'd.storage_address',
                        'a.materiel_mean_cost',
                        'a.in_storage_num'
                    )
                        ->from('storage_manage as a')
                        ->leftJoin('materiel_type as b', 'b.id', '=', 'a.type_id')
                        ->leftJoin('materiel_class as c', 'c.id', '=', 'a.materiel_class_id')
                        ->leftJoin('storage as d', 'd.id', '=', 'a.storage_id')
                        ->where([
                            'a.id' => $val['storage_manage_id'],
                            'a.delete_flag' => 0,
                            'a.main_id' => $data['main_id']
                        ])
                        ->first();

                    if (empty($storageManageInfo)) {
                        return [
                            'code' => 1,
                            'msg' => '套餐内商品无库存信息，无法完成出库',
                            'data' => ''
                        ];
                    }

                    if ($storageManageInfo['in_storage_num'] < ($leftNum * $val['num'])) {
                        return [
                            'code' => 1,
                            'msg' => '套餐内商品库存不足，无法完成出库',
                            'data' => ''
                        ];
                    }

                    StorageManageModel::where('id', $val['storage_manage_id'])
                        ->decrement('in_storage_num', $leftNum * $val['num']);

                    $prepareInfo = SellPackagePrepareOutLogModel::where('sell_id', $id)
                        ->where('package_id', $value['package_id'])->first();

                    if(empty($prepareInfo)) {
                        StorageManageModel::where('id', $storageManageInfo['id'])
                            ->decrement('virtual_storage_num', $value['num'] * $val['num']);
                    }

                    //销售单成本表
                    $logOutPackageArr[$kk]['package_id'] = $value['package_id'];
                    $logOutPackageArr[$kk]['out_time'] = strtotime(date('Y-m-d'));
                    $logOutPackageArr[$kk]['mean_cost'] = $storageManageInfo['materiel_mean_cost'];
                    $logOutPackageArr[$kk]['num'] = $leftNum;
                    $logOutPackageArr[$kk]['price'] = $SellPackageDetailInfo['price'];
                    $logOutPackageArr[$kk]['all_id_type'] = 2;
                    $logOutPackageArr[$kk]['all_id'] = $id;
                    $logOutPackageArr[$kk]['user_id'] = $data['user_id'];
                    $logOutPackageArr[$kk]['main_id'] = $data['main_id'];
                    $logOutPackageArr[$kk]['created_at'] = time();

                    //出库套餐信息记录
                    $logPackageArr['package_id'] = $value['package_id'];
                    $logPackageArr['package_name'] = $SellPackageDetailInfo['package_name'];
                    $logPackageArr['num'] = $leftNum;
                    $logPackageArr['all_id_type'] = 2;
                    $logPackageArr['all_id'] = $id;
                    $logPackageArr['user_id'] = $data['user_id'];
                    $logPackageArr['main_id'] = $data['main_id'];
                    $logPackageArr['remark'] = $value['remark'];
                    $logPackageArr['created_at'] = time();

                    $logpackageNewId = LogPackageModel::insertGetId($logPackageArr);

                    LogPackageContentModel::insert([
                        'log_package_id' => $logpackageNewId,
                        'package_id' => $value['package_id'],
                        'storage_id' => $val['storage_id'],
                        'storage_name' => $storageManageInfo['storage_name'],
                        'storage_address' => $storageManageInfo['storage_address'],
                        'materiel_class_id' => $storageManageInfo['materiel_class_id'],
                        'materiel_class_name' => $storageManageInfo['materiel_class_name'],
                        'materiel_class_no' => $storageManageInfo['materiel_class_no'],
                        'materiel_type_id' => $storageManageInfo['type_id'],
                        'materiel_name' => $storageManageInfo['materiel_name'],
                        'type_name' => $storageManageInfo['type_name'],
                        'materiel_no' => $storageManageInfo['materiel_no'],
                        'operate_num' => $leftNum * $val['num'],
                        'out_storage_manage_id' => $storageManageInfo['id'],
                        'last_storage_num' => $storageManageInfo['in_storage_num'],
                        'next_storage_num' => $storageManageInfo['in_storage_num'] - ($leftNum * $val['num']),
                        'all_id_type' => 4,
                        'all_id' => $id,
                        'user_id' => $data['user_id'],
                        'main_id' => $data['main_id'],
                        'created_at' => time()
                    ]);

                    $sellOutStoragePackage = SellOutStoragePackageModel::where([
                        'package_id' => $value['package_id'],
                        'sell_id' => $id
                    ])->first();

                    if (empty($sellOutStoragePackage)) {
                        $newId = SellOutStoragePackageModel::insertGetId([
                            'package_id' => $value['package_id'],
                            'price' => $SellPackageDetailInfo['price'],
                            'num' => $leftNum,
                            'sell_id' => $id,
                            'remark' => empty($value['remark'])?:$value['remark']
                        ]);

                        SellOutStoragePackageContentModel::insert([
                            'type_id' => $storageManageInfo['type_id'],
                            'storage_id' => $val['storage_id'],
                            'package_content_id' => $val['package_content_id'],
                            'storage_manage_id' => $val['storage_manage_id'],
                            'o_s_package_id' => $newId,
                            'sell_id' => $id,
                            'num' => $leftNum * $val['num'],
                            'user_id' => $data['user_id'],
                            'main_id' => $data['main_id'],
                            'created_at' => time()
                        ]);
                    } else {
                        SellOutStoragePackageModel::where('id', $sellOutStoragePackage['id'])
                            ->increment('num', $leftNum, [
                                'remark' => empty($value['remark'])?'':$value['remark']
                            ]);

                        SellOutStoragePackageContentModel::where('o_s_package_id', $sellOutStoragePackage['id'])
                            ->increment('num', $leftNum * $val['num']);
                    }
                }

                LogOutPackageModel::insert($logOutPackageArr);
                SellPackageDetailModel::where('sell_id', $id)
                    ->where('package_id', $value['package_id'])
                    ->increment('out_num', $leftNum);
            }
            DB::commit();
            return true;
        }
        catch(\Exception $e) {
            DB::rollBack();
            Log::debug('销售单部分出库-套餐:'.var_export($e->getMessage(),true));
            return ['code' => 1, 'msg' => $e->getMessage(), 'data' => ''];
        }
    }

    /**
     * 撤销
     * change 在 2021/11/11 14:32 创建
     * @param $id    主键
     * @param $type  1-销售 2-退货  3-报溢报损
     */
    static public function repeal($id,$type)
    {
        switch($type) {
            case 1:
                $result = self::sellRepeal($id);
                break;
            case 2:
                $result = self::salesRepeal($id);
                break;
            case 3:
                break;
        }

        return $result;
    }

    //销售单撤销
    static private function sellRepeal($id)
    {
        DB::beginTransaction();

        try {
            $sellModel = SellModel::find($id);
            if($sellModel['repeal_status']) {
                throw new \Exception('销售单已撤销，无法重复撤销');
            }

            if($sellModel['out_status']==1 || $sellModel['out_status']==2){//全部或部分
                $res = StorageManageService::cancelOut(2, $id);
                if($res!=1){
                    return $res;
                }

                $packageRes = StorageManageService::cancelPackageOut(2, $id);

                if($packageRes!=1){
                    return $packageRes;
                }
            }

            if($sellModel['prepare_out_status'] == 1) {
                $materielLog = SellMaterielPrepareOutLogModel::where('sell_id', $id)->get()->toArray();
                $packageLogInfo = SellPackageContentPrepareOutLogModel::where('sell_id', $id)->get()->toArray();

                foreach($materielLog as $value) {
                    StorageManageModel::where('id', $value['storage_manage_id'])->increment('virtual_storage_num', $value['num']);
                }

                foreach($packageLogInfo as $val) {
                    StorageManageModel::where('id', $val['storage_manage_id'])->increment('virtual_storage_num', $val['total_num']);
                }
            }

            SellGoodsDetail::where(['main_id'=>$sellModel['main_id'],'sell_id'=>$id])->update(['repeal_status'=>1]);//销售商品撤销
            SellPackageContentModel::where('sell_id', $id)->update(['repeal_status'=>1]);//销售套餐商品撤销
            SellPackageDetailModel::where('sell_id', $id)->update(['repeal_status'=>1]);//销售套餐撤销
            CheckModel::where(['main_id'=>$sellModel['main_id'],'all_id'=>$id,'type'=>2])->update(['repeal_status'=>1]);//更新销售审批状态
            TallyModel::where(['main_id'=>$sellModel['main_id'],'order_no'=>$sellModel['order_no']])->update(['delete_flag'=>1]);
            $sellModel->repeal_status = 1;

            //获取生产订单信息
            $productOrderModel = ProductOrderModel::where([
                'product_source' => 1,
                'product_source_id' => $id,
            ])
                ->first();

            if(!empty($productOrderModel)) {
                ProductOrderModel::where('id', $productOrderModel['id'])->update(['is_cancel' => 1]);

                if($productOrderModel['product_status'] == 2) {
                    $productSlaveContentStorage = ProductSlaveContentStorageModel::where('product_order_id', $productOrderModel['id'])
                        ->get()->toArray();

                    $serialData = [];
                    $serialStorageData = [];
                    $storageData = [];
                    foreach($productSlaveContentStorage as $v) {
                        $storageManageInfo = StorageManageModel::where('id', $v['storage_manage_id'])->first();

                        if($v['serial_id'] != 0) {
                            $serialData[] = [
                                'id' => $v['serial_id'],
                                'sell_id' => 0,
                                'status' => 1,
                            ];

                            $serialStorageData[] = [
                                'id' => $storageManageInfo['id'],
                                'in_storage_num' => $storageManageInfo['in_storage_num'] + 1,
                                'virtual_storage_num' => $storageManageInfo['virtual_storage_num'] + 1,
                                'delete_flag' => 0
                            ];
                        }
                        else {
                            $storageData[] = [
                                'id' => $storageManageInfo['id'],
                                'in_storage_num' => $storageManageInfo['in_storage_num'] + $v['num'],
                                'virtual_storage_num' => $storageManageInfo['virtual_storage_num'] + $v['num'],
                                'delete_flag' => 0
                            ];
                        }
                    }

                    if(!empty($serialData)) {
                        batch()->update(new SerialNumberModel, $serialData, 'id');
                    }
                    if(!empty($serialStorageData)) {
                        batch()->update(new StorageManageModel, $serialStorageData, 'id');
                    }
                    if(!empty($storageData)) {
                        batch()->update(new StorageManageModel, $storageData, 'id');
                    }

                    LogOutStorageModel::where([
                        'all_id_type' => 3,
                        'all_id' => $productOrderModel['id']
                    ])
                        ->update(['is_cancel' => 1]);
                }
            }

            DB::commit();
            return $sellModel->save();
        }
        catch(\Exception $e) {
            DB::rollBack();
            Log::debug('销售单撤销异常：'.var_export($e->getMessage(), true));
            return ['code' => 1, 'msg' => $e->getMessage(), 'data' => ''];
        }
    }

    static public function salesRepeal($id)
    {
        $salesReturnModel = SalesReturnModel::find($id);

        DB::beginTransaction();

        try {
            $result = ['code' => 0, 'msg' => 'success', 'data' => ''];
            if(in_array($salesReturnModel['out_status'], [1, 2])){//部分
                if(!empty(SalesReturnGoodsDetailModel::where('return_id', $id)->first())) {
                    //出库参数-普通商品
                    $res = StorageManageService::cancelIn(2, $id);

                    switch($res) {
                        case 0:
                            $result = ['code' => 1, 'msg' => '商品被删除，无法撤销', 'data' => ''];
                            break;
                        case 1:
                            $result = ['code' => 0, 'msg' => 'success', 'data' => ''];
                            break;
                        case 2:
                            $result = ['code' => 1, 'msg' => '库存数量不足，无法撤销', 'data' => ''];
                            break;
                    }

                    $serialInfo = SalesOutSerialNumberModel::select('b.id')
                                ->from('sales_out_serial_number as a')
                                ->leftJoin('serial_number as b','b.serial_no','=','a.serial_number')
                                ->leftJoin('serial_number as c','c.goods_id','=','a.type_id')
                                ->where(['a.return_id'=>$id,'a.status'=>1])
                                ->distinct()
                                ->get()->toArray();

                            if(!empty($serialInfo)){
                                $ids = array_map('array_shift', $serialInfo);
                                SerialNumberModel::whereIn('id',$ids)->update(['status'=>0]);
                                SalesOutSerialNumberModel::where(['return_id'=>$id,'status'=>1])->update(['status'=>0]);
                            }
                }

                if(!empty(SalesReturnPackageModel::where('return_id', $id)->first())) {
                    $res1 = StorageManageService::cancelPackageIn(3, $id);

                    switch($res1) {
                        case 0:
                            $result = ['code' => 1, 'msg' => '库存商品不存在，无法完成对套餐的撤销', 'data' => ''];
                            break;
                        case 1:
                            $result = ['code' => 0, 'msg' => 'success', 'data' => ''];
                            break;
                        case 3:
                            $result = ['code' => 1, 'msg' => '库存数量不足，无法完成撤销', 'data' => ''];
                            break;
                        case 2:
                            $result = ['code' => 1, 'msg' => '套餐入库撤销异常，请重试', 'data' => ''];
                            break;
                    }

                    $serialInfo = SalesReturnPackageSerialNumberModel::select('b.id')
                    ->from('sales_out_serial_number as a')
                    ->leftJoin('serial_number as b','b.serial_no','=','a.serial_number')
                    ->leftJoin('serial_number as c','c.goods_id','=','a.type_id')
                    ->where(['a.return_id'=>$id,'status'=>1])
                    ->distinct()
                    ->get()->toArray();
                    if(!empty($serialInfo)){
                        $ids = array_map('array_shift', $serialInfo);
                        SerialNumberModel::whereIn('id',$ids)->update(['status'=>0]);
                        SalesReturnPackageSerialNumberModel::where(['return_id'=>$id,'status'=>1])->update(['status'=>0]);
                    }
                }
            }

            $salesReturnModel->repeal_status = 1;
            $salesReturnModel->save();
            DB::commit();
            return $result;
        }
        catch(\Exception $e) {
            Log::debug('退货单撤销:'.var_export($e->getMessage(), true));
            DB::rollBack();
            return ['code' => 1, 'msg' => $e->getMessage(), 'data' => ''];
        }


    }
}
